﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class PipeRoundBeam : IExternalCommand
	{
		private Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector != null && connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && ((int)connector2.ConnectorType == 1 || (int)connector2.ConnectorType == 2 || (int)connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			Result result;
			try
			{
				if (commandData == null)
				{
					throw new NotImplementedException();
				}
				UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
				Document document = activeUIDocument.Document;
				Selection selection = activeUIDocument.Selection;
				RevitVersionFuncs.ClearSelection(selection);
				string text = "水管升降";
				transaction = new Transaction(document, text);
				transaction.Start();
				IList<Pipe> list = new List<Pipe>();
				IList<XYZ> list2 = new List<XYZ>();
				ISelectionFilter selectionFilter = new PipeSelectionFilter();
				Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择所要升降的水管");
				Pipe pipe = document.GetElement(reference) as Pipe;
				XYZ xyz = selection.PickPoint("请选择升降的起点位置");
				list2.Add(xyz);
				XYZ xyz2 = selection.PickPoint("请选择升降的终点位置");
				list2.Add(xyz2);
				List<ElementId> list3 = new List<ElementId>();
				List<Pipe> list4 = new List<Pipe>();
				ConnectorSetIterator connectorSetIterator = pipe.ConnectorManager.Connectors.ForwardIterator();
				new List<XYZ>();
				ICollection<ElementId> copyElem = new List<ElementId>();
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
				XYZ project = hypiping.GetProject(xyz, true);
				XYZ project2 = hypiping.GetProject(xyz2, true);
				YJKLine hyline = new YJKLine(project, project2);
				bool flag = false;
				int num = 0;
				while (connectorSetIterator.MoveNext())
				{
					num++;
					Connector connector = connectorSetIterator.Current as Connector;
					if (connector.IsConnected && hyline.IsPointOnLine(connector.Origin))
					{
						Connector connectConnector = this.GetConnectConnector(connector);
						connectorSetIterator = connectConnector.ConnectorManager.Connectors.ForwardIterator();
						Element owner = connectConnector.ConnectorManager.Owner;
						int integerValue = owner.Category.Id.IntegerValue;
						if (integerValue == -2008055 && !list3.Contains(owner.Id))
						{
							list3.Add(owner.Id);
						}
						if (integerValue == -2008049 && !list3.Contains(owner.Id))
						{
							list3.Add(owner.Id);
							flag = true;
						}
					}
					if ((flag && list3.Count == 3) || (list3.Count == 1 && !flag) || num > 20)
					{
						break;
					}
				}
				int num2 = 0;
				while (connectorSetIterator.MoveNext())
				{
					num2++;
					Connector connector2 = connectorSetIterator.Current as Connector;
					if (connector2.IsConnected && hyline.IsPointOnLine(connector2.Origin))
					{
						Connector connectConnector2 = this.GetConnectConnector(connector2);
						connectorSetIterator = connectConnector2.ConnectorManager.Connectors.ForwardIterator();
						Element owner2 = connectConnector2.ConnectorManager.Owner;
						if (owner2 is Pipe && owner2.Id != pipe.Id)
						{
							list4.Add(owner2 as Pipe);
						}
					}
					if (list4.Count == 1 || num2 > 10)
					{
						break;
					}
				}
				if (list3.Count > 0)
				{
					copyElem = ElementTransformUtils.CopyElements(document, list3, new XYZ(100.0, 100.0, 100.0));
				}
				if (list3.Count == 3)
				{
					foreach (ElementId elementId in list3)
					{
						document.Delete(elementId);
					}
					document.Regenerate();
					hypiping.Combine(list4.ElementAt(0));
				}
				else if (list3.Count == 1)
				{
					foreach (ElementId elementId2 in list3)
					{
						document.Delete(elementId2);
					}
					try
					{
						hypiping.Combine(list4.ElementAt(0));
					}
					catch
					{
					}
					try
					{
						ElementId id = pipe.Id;
						string name = document.GetElementById(id).Name;
					}
					catch
					{
						ElementId id2 = list4.ElementAt(0).Id;
						string name2 = document.GetElementById(id2).Name;
						pipe = list4.ElementAt(0);
					}
					document.Regenerate();
				}
				else if (list3.Count != 0)
				{
					transaction.Commit();
					YJKMessageBox.Error("搜索带阀件的升降失败！请重新选择！");
					return Autodesk.Revit.UI.Result.Failed;
				}
				document.Regenerate();
				list.Add(pipe);
				list.Add(pipe);
				YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(list[0]);
				IList<XYZ> list5 = new List<XYZ>();
				list5 = list2;
				if (hypiping2.IsPointOnPipingCurve(hypiping2.GetProject(list2[0], true)) && hypiping2.IsPointOnPipingCurve(hypiping2.GetProject(list2[1], true)))
				{
					XYZ globalOnCenterLinePoint = hypiping2.GetGlobalOnCenterLinePoint(list2[1]);
					XYZ globalOnCenterLinePoint2 = hypiping2.GetGlobalOnCenterLinePoint(list2[0]);
					list5.Clear();
					list5.Add(globalOnCenterLinePoint);
					list5.Add(globalOnCenterLinePoint2);
				}
				PipeRoundBeamForm pipeRoundBeamForm = new PipeRoundBeamForm(list5);
				DialogResult dialogResult = pipeRoundBeamForm.ShowDialog();
				if (DialogResult.OK == dialogResult)
				{
					double offSet = pipeRoundBeamForm.offSet;
					double angle = pipeRoundBeamForm.angle;
					new HYPipeConnect().PipeRoundBeam(list, list2, this.mmToFeet(offSet), angle, copyElem);
				}
				transaction.Commit();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (1 == (int)transaction.GetStatus())
				{
					transaction.RollBack();
				}
			}
			return result;
		}

		private double mmToFeet(double mm)
		{
			return mm * 0.0032808399;
		}
	}
}
